﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace RecipeRecommender
{
    public partial class Form1 : Form
    {


        private List<Ingredient> ingredientList;
        private List<Ingredient> queryIngredientList;
        private List<Ingredient> avoidedIngredientList;
        private List<CookingMethod> cookingMethodList;
        private List<MealType> mealTypeList;
        private List<Cuisine> cuisineList;
        private Recipe rRecipe;
        private int pageCounter;
        private int totalPageCounter;
        List<Recipe> relevantRecipes;
        Recipe cCurrentDisplayedRecipe;
        RecipeQuery cCurrentRecipeQuery;

        public Form1()
        {
            InitializeComponent();
            queryIngredientList = new List<Ingredient>();
            avoidedIngredientList = new List<Ingredient>();
            //ingredientList = new List<Ingredient>();
            //cookingMethodList = new List<CookingMethod>();
           // mealTypeList = new List<MealType>();
            //cuisineList = new List<Cuisine>();

            IngredientUtil.setAllIngredients();
            CookingMethodUtil.setAllCookingMethods();
            CuisineUtil.setAllCuisines();
            MealTypeUtil.setAllMealTypes();
            RecipeUtil.setAllRecipes();
            IngredientUtil.setVegetarianIngredientMap();
            RecipeUtil.setSimilarityWeight();

            ingredientList = IngredientUtil.IngredientList;
            cookingMethodList = CookingMethodUtil.CookingMethodList;
            mealTypeList = MealTypeUtil.MealTypeList;
            cuisineList = CuisineUtil.CuisineList;

            //HelperUtil.createRecipeFiles();

            foreach (Ingredient ingredient in ingredientList)
            {
                ingredientComboBox.Items.Add(ingredient.ToString());
                avoidedIngredientComboBox.Items.Add(ingredient.ToString());
            }

            mealTypeComboBox.Items.Add("[---------Any---------]");
            foreach (MealType mealType in mealTypeList)
                mealTypeComboBox.Items.Add(mealType.Name);

            cuisineComboBox.Items.Add("[---------Any---------]");
            foreach (Cuisine cuisine in cuisineList)
                cuisineComboBox.Items.Add(cuisine.Name);

            cookingMethodComboBox.Items.Add("[---------Any---------]");
            foreach (CookingMethod cookingMethod in cookingMethodList)
                cookingMethodComboBox.Items.Add(cookingMethod.Name);

            cuisineComboBox.SelectedIndex = 0;
            cookingMethodComboBox.SelectedIndex = 0;
            mealTypeComboBox.SelectedIndex = 0;

            for (int i = 1; i<=12; i++)
                noOfResultsComboBox.Items.Add(i*10);
            noOfResultsComboBox.SelectedIndex = 11;

            /*
            ingredientList.Add(new CSpinach());
            ingredientList.Add(new CVegetable());
            ingredientList.Add(new CCabbage());
            ingredientList.Add(new CMeat());
            ingredientList.Add(new CChicken());
            ingredientList.Add(new CBeef());
            ingredientList.Add(new CPork());
            */

            //cLoader = new CCaseLoader();


            /*

            CVegetable cVeg = new CVegetable();

            bool bType = object.ReferenceEquals(cVeg.GetType(), cList[0].GetType());
            if (bType)
            {
                listBox1.Items.Add("the references are equal");
            }
            Type t = cList[0].GetType();

            bType = object.ReferenceEquals(cVeg.GetType(),t.BaseType);
            if (bType)
            {
                //listBox1.Items.Add("the references are base type related");
            } 

           */

            // Testing Codes by Mark

            
            Ingredient salmon = IngredientUtil.getIngredientByName("Salmon");
            Ingredient seabass = IngredientUtil.getIngredientByName("Seabass");
            Ingredient beef = IngredientUtil.getIngredientByName("Beef");
            Ingredient meat = IngredientUtil.getIngredientByName("Meat");
            Ingredient vegetable = IngredientUtil.getIngredientByName("Vegetable");
            double sim1 = IngredientUtil.getSimilarityScore(salmon, seabass);
            double sim2 = IngredientUtil.getSimilarityScore(salmon, beef);
            double sim3 = IngredientUtil.getSimilarityScore(meat, vegetable);

            Console.WriteLine("Similarity Score Between Salmon & Seabass = 67, Result = " + sim1);
            Console.WriteLine("Similarity Score Between Salmon & Beef = 40, Result = " + sim2);
            Console.WriteLine("Similarity Score Between Meat & Vegetable = 0, Result = " + sim3);

            List<Ingredient> ingredientList1 = new List<Ingredient>();
            ingredientList1.Add(salmon);
            ingredientList1.Add(beef);

            List<Ingredient> ingredientList2 = new List<Ingredient>();
            ingredientList2.Add(beef);
            ingredientList2.Add(vegetable);

            List<Ingredient> ingredientList3 = new List<Ingredient>();
            ingredientList3.Add(meat);
            ingredientList3.Add(salmon);

            double sim4 = IngredientUtil.getSimilarityScore(ingredientList1, ingredientList2);
            double sim5 = IngredientUtil.getSimilarityScore(ingredientList1, ingredientList3);
            double sim6 = IngredientUtil.getSimilarityScore(ingredientList2, ingredientList3);

            Console.WriteLine("Similarity Score Between ingredientList1 & ingredientList2 = 50, Result = " + sim4);
            Console.WriteLine("Similarity Score Between ingredientList1 & ingredientList3 = 86, Result = " + sim5);
            Console.WriteLine("Similarity Score Between ingredientList2 & ingredientList3 = 37, Result = " + sim6);
            recipeAdaptButton.Enabled = false ;

            cCurrentRecipeQuery = new RecipeQuery();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }


        private void selectIngredientButton_Click(object sender, EventArgs e)
        {
            if (ingredientComboBox.SelectedIndex == -1) return;
            Ingredient ingredient = ingredientList[ingredientComboBox.SelectedIndex];

            if (!queryIngredientList.Contains(ingredient))
            {
                queryIngredientList.Add(ingredient);
                ingredientListBox.Items.Add(ingredient.Name);
            }
        }

        private void clearButton_Click(object sender, EventArgs e)
        {
            ingredientListBox.Items.Clear();
            queryIngredientList.Clear();
        }

        private void removeButton_Click(object sender, EventArgs e)
        {
            if (ingredientListBox.SelectedIndex == -1) return;
            queryIngredientList.RemoveAt(ingredientListBox.SelectedIndex);
            ingredientListBox.Items.RemoveAt(ingredientListBox.SelectedIndex);
        }

        private void searchButton_Click(object sender, EventArgs e)
        {
            RecipeQuery recipeQuery = new RecipeQuery();
            Cuisine cuisine = null;
            MealType mealType =  null;
            CookingMethod cookingMethod = null;
            int? cookingTime = null;

            if (cuisineComboBox.SelectedIndex != -1 && cuisineComboBox.SelectedIndex != 0)
                cuisine = cuisineList[cuisineComboBox.SelectedIndex-1];
            if (mealTypeComboBox.SelectedIndex != -1 && mealTypeComboBox.SelectedIndex != 0)
                mealType = mealTypeList[mealTypeComboBox.SelectedIndex-1];
            if (cookingMethodComboBox.SelectedIndex != -1 && cookingMethodComboBox.SelectedIndex != 0)
                cookingMethod = cookingMethodList[cookingMethodComboBox.SelectedIndex-1];
            if (!cookingTimeTextBox.Text.Equals(""))
                cookingTime = Convert.ToInt32(cookingTimeTextBox.Text);

            recipeQuery.Cuisine = cuisine;
            recipeQuery.CookingMethod = cookingMethod;
            recipeQuery.CookingTime = cookingTime;
            recipeQuery.MealType = mealType;
            recipeQuery.Ingredients = queryIngredientList;
            recipeQuery.AvoidedIngredients = avoidedIngredientList;
            recipeQuery.Name = nameTextBox.Text;
            cCurrentRecipeQuery = recipeQuery;

            if (yesHalal.Checked)
                recipeQuery.Halal = true;
            else if (noHalal.Checked)
                recipeQuery.Halal = false;
            else if (anyHalal.Checked)
                recipeQuery.Halal = null;

            if (yesHealthy.Checked)
                recipeQuery.Healthy = true;
            else if (noHealthy.Checked)
                recipeQuery.Healthy = false;
            else if (anyHealthy.Checked)
                recipeQuery.Healthy = null;

            if (yesHealthy.Checked)
                recipeQuery.Healthy = true;
            else if (noHealthy.Checked)
                recipeQuery.Healthy = false;
            else if (anyHealthy.Checked)
                recipeQuery.Healthy = null;

            if (yesSpicy.Checked)
                recipeQuery.Spicy = true;
            else if (noSpicy.Checked)
                recipeQuery.Spicy = false;
            else if (anySpicy.Checked)
                recipeQuery.Spicy = null;

            if (yesVegetarian.Checked)
                recipeQuery.Vegetarian = true;
            else if (noVegetarian.Checked)
                recipeQuery.Vegetarian = false;
            else if (anyVegetarian.Checked)
                recipeQuery.Vegetarian = null;
            
          int noOfPageRetrieved = (noOfResultsComboBox.SelectedIndex + 1) * 10;
          relevantRecipes = RecipeUtil.getRelevantRecipes(recipeQuery, noOfPageRetrieved);
          pageCounter = 1;
          //totalPageCounter = relevantRecipes.Count;
          totalPageCounter = relevantRecipes.Count;
          populatePage(pageCounter);

            //  List<Recipe> cRelevant = cLoader.getRelevantCases(recipeQuery);
    

            // Testing
         // HelperUtil.printAllIngredients();
         // HelperUtil.createRecipeFiles();



            Form2 form2 = new Form2();

            form2.Show();
            int nCount = 1;
            foreach (Recipe recipe in relevantRecipes)
            {
                form2.AddString(nCount.ToString()+ ". "+ recipe.Name + "\n");
                nCount++;
                form2.AddString("Similarity: " + recipe.Similarity + "\n");
            }
        }

        private void populatePage(int page)
        {
            rRecipe = relevantRecipes.ElementAt(page-1);
            cCurrentDisplayedRecipe = rRecipe;//store the current displayed recipe
            recipeAdaptButton.Enabled = true;
            populateFieldsWithRecipe(rRecipe);
            pageTextBox.Text = page.ToString();
            totalPageTextBox.Text = totalPageCounter.ToString();
        }

        private void populateFieldsWithRecipe(Recipe r)
        {
            rCuisineTextBox.Text = r.Cuisine.Name;
            rMealTypetextBox.Text = r.MealType.Name;
            rCookingMethodTextBox.Text = r.CookingMethod.Name;
            rCookingInstructionRichTextBox.Text = r.CookingInstructions;
            rNameTextBox.Text = r.Name;
            similarityTextBox.Text = r.Similarity.ToString();
            rHalalCheckBox.Checked = (bool)r.Halal;
            rHealthyCheckBox.Checked = (bool)r.Healthy;
            rVegetarianCheckBox.Checked = (bool)r.Vegetarian;
            rSpicyCheckBox.Checked = (bool)r.Spicy;
            rCookingTimeTextBox.Text = r.CookingTime.ToString();
            rServingPortionTextBox.Text = r.ServingPortion.ToString();
            rIngredientListBox.Items.Clear();
            foreach (Ingredient ingredient in r.Ingredients)
            {
                rIngredientListBox.Items.Add(ingredient.Name);
            }
            
        }

        private void nextButton_Click(object sender, EventArgs e)
        {
            if (pageCounter < totalPageCounter) pageCounter++;
            populatePage(pageCounter);
        }

        private void prevButton_Click(object sender, EventArgs e)
        {
            if (pageCounter > 1) pageCounter--;
            populatePage(pageCounter);
        }

        private void lastButton_Click(object sender, EventArgs e)
        {
            populatePage(totalPageCounter);
            pageCounter = totalPageCounter;
        }

        private void firstButton_Click(object sender, EventArgs e)
        {
            populatePage(1);
            pageCounter = 1;
        }

        private void goToButton_Click(object sender, EventArgs e)
        {
            try
            {
                int page = Convert.ToInt32(pageTextBox.Text);
                if (page >= 1 && page <= totalPageCounter)
                {
                   populatePage(page);
                   pageCounter = page;
                }
            }
            catch (Exception ex)
            {
            }
        }


        private void resetButton_Click(object sender, EventArgs e)
        {
            nameTextBox.Text = "";
            ingredientListBox.Items.Clear();
            queryIngredientList.Clear();
            avoidedIngredientListBox.Items.Clear();
            avoidedIngredientList.Clear();
            cuisineComboBox.SelectedIndex = 0;
            cookingMethodComboBox.SelectedIndex = 0;
            mealTypeComboBox.SelectedIndex = 0;
            anyHalal.Checked = true;
            anyHealthy.Checked = true;
            anySpicy.Checked = true;
            anyVegetarian.Checked = true;
            cookingTimeTextBox.Text = "";

        }

        private void selectAvoidedIngredientButton_Click(object sender, EventArgs e)
        {
            if (avoidedIngredientComboBox.SelectedIndex == -1) return;
            Ingredient ingredient = ingredientList[avoidedIngredientComboBox.SelectedIndex];

            if (!avoidedIngredientList.Contains(ingredient))
            {
                avoidedIngredientList.Add(ingredient);
                avoidedIngredientListBox.Items.Add(ingredient.Name);
            }
        }

        private void removeSelectedIngredientButton_Click(object sender, EventArgs e)
        {
            if (avoidedIngredientListBox.SelectedIndex == -1) return;
            avoidedIngredientList.RemoveAt(avoidedIngredientListBox.SelectedIndex);
            avoidedIngredientListBox.Items.RemoveAt(avoidedIngredientListBox.SelectedIndex);
        }

        private void clearSelectedIngredientButton_Click(object sender, EventArgs e)
        {
            avoidedIngredientListBox.Items.Clear();
            avoidedIngredientList.Clear();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form4 cAdaptationForm = new Form4(cCurrentDisplayedRecipe, cCurrentRecipeQuery);
            cAdaptationForm.Show();
        }


    }
}
